package tech.aistar.snake;

import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;

/**
 * 本类用来演示:
 *
 * @author: success
 * @date: 2021/3/25 3:00 下午
 */
public class SnakeDemo {

    //1. 定义食物 - 特点:不可重复
    private Set<Node> foods = new HashSet<>();

    //2. 定义蛇的对象
    private Snake snake;

    public Snake getSnake() {
        return snake;
    }

    //4. 定义游戏墙的界限
    private final int ROWS = 20;
    private final int COLS = 20;

    //3. 构造方法
    public SnakeDemo(){
        //组合关系 - 强调整体和部分的关系 - 不可分割 - 强
        this.snake = new Snake();

        //初始化食物
        initFoods(3);
    }

    /**
     * 初始化食物 - 给foods的Set集合中添加数据
     * @param i 食物的数量
     */
    private void initFoods(int i) {
        do{

            //随机一个横坐标
            int m = (int) (Math.random()*18+1);//[1,18]
            int n = (int) (Math.random()*18+1);
            Node food = new Node(m,n);
            if(snake.contains(m,n)){//蛇节点包含m,n
                continue;
            }
            //随机出一个纵坐标
            foods.add(food);
            if(foods.size()==i)
                break;
        }while(true);
    }

    //4. 输出游戏的界面
    public void startGame(){
        String[][] arr = new String[ROWS][COLS];

        for (int i = 0; i < ROWS; i++) {
            for (int j = 0; j < COLS; j++) {
                if(i==0 || i==ROWS-1 || j==0 || j==COLS-1){
                    arr[i][j] = "*";
                }else if(foods.contains(new Node(i,j))){
                    arr[i][j] = "0";//食物...
                }else if(snake.contains(i,j)){
                    arr[i][j] = "#";
                }
                else{
                    arr[i][j] = " ";
                }
            }
        }

        //遍历
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr[i].length; j++) {
                //System.out.print(arr[i][j]+"\t");
                System.out.printf("%2s",arr[i][j]);
            }
            System.out.println();
        }
        System.out.println("使用说明:>w ↑  a ←  s ↓  d →");
    }



    //2. 成员内部类
    public class Snake{
        private LinkedList<Node> snakes = new LinkedList<>();

        public static final int UP = -1;
        public static final int DOWN = 1;
        public static final int LEFT = -2;
        public static final int RIGHT = 2;

        public int dir;//方向


        public Snake(){
            snakes.add(new Node(5,10));
            snakes.add(new Node(5,11));
            snakes.add(new Node(5,12));

            dir = LEFT;//默认的方向
        }

        public boolean contains(int x,int y){
            return snakes.contains(new Node(x,y));
        }

        //蛇移动
        public void step(int dir){
            if(this.dir + dir == 0)
                throw new RuntimeException("Game Over!蛇不能撞到自身!");

            this.dir = dir;
            step();
        }

        //蛇真的在走一步了...
        private void step() {
            //1. 获取当前蛇头.
            Node header = snakes.getFirst();
            int x = header.getX();//纵
            int y = header.getY();//横
            switch (dir){
                case UP:
                    x--;
                    break;
                case DOWN:
                    x++;
                    break;
                case LEFT:
                    y--;
                    break;
                case RIGHT:
                    y++;
                    break;
            }
            //得到新的蛇头
            header = new Node(x,y);

            snakes.addFirst(header);

            if(foods.remove(header)){
                return;
            }

            snakes.removeLast();//删除最后一个节点
        }
    }
}
